/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package multi.agent.simulation.dao;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.persistence.*;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import multi.agent.simulation.dao.exceptions.NonexistentEntityException;
import multi.agent.simulation.dao.exceptions.PreexistingEntityException;
import multi.agent.simulation.entity.Nodo;
import multi.agent.simulation.entity.Rutas;
import multi.agent.simulation.entity.RutasPK;
import org.eclipse.persistence.internal.expressions.ParameterExpression;

/**
 *
 * @author Owner
 */
public class RutasJpaController implements Serializable {

    public RutasJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Rutas rutas) throws PreexistingEntityException, Exception {
        if (rutas.getRutasPK() == null) {
            rutas.setRutasPK(new RutasPK());
        }
        rutas.getRutasPK().setDesde(rutas.getDesde().getId());
        rutas.getRutasPK().setHasta(rutas.getHasta().getId());
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Nodo nodo = rutas.getHasta();
            if (nodo != null) {
                nodo = em.getReference(nodo.getClass(), nodo.getId());
                rutas.setHasta(nodo);
            }
            Nodo nodo1 = rutas.getDesde();
            if (nodo1 != null) {
                nodo1 = em.getReference(nodo1.getClass(), nodo1.getId());
                rutas.setDesde(nodo1);
            }
            em.persist(rutas);
            if (nodo != null) {
                nodo.getRutasCollection().add(rutas);
                nodo = em.merge(nodo);
            }
            if (nodo1 != null) {
                nodo1.getRutasCollection().add(rutas);
                nodo1 = em.merge(nodo1);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findRutas(rutas.getRutasPK()) != null) {
                throw new PreexistingEntityException("Rutas " + rutas + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Rutas rutas) throws NonexistentEntityException, Exception {
        rutas.getRutasPK().setDesde(rutas.getDesde().getId());
        rutas.getRutasPK().setHasta(rutas.getHasta().getId());
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Rutas persistentRutas = em.find(Rutas.class, rutas.getRutasPK());
            Nodo nodoOld = persistentRutas.getHasta();
            Nodo nodoNew = rutas.getHasta();
            Nodo nodo1Old = persistentRutas.getDesde();
            Nodo nodo1New = rutas.getDesde();
            if (nodoNew != null) {
                nodoNew = em.getReference(nodoNew.getClass(), nodoNew.getId());
                rutas.setHasta(nodoNew);
            }
            if (nodo1New != null) {
                nodo1New = em.getReference(nodo1New.getClass(), nodo1New.getId());
                rutas.setDesde(nodo1New);
            }
            rutas = em.merge(rutas);
            if (nodoOld != null && !nodoOld.equals(nodoNew)) {
                nodoOld.getRutasCollection().remove(rutas);
                nodoOld = em.merge(nodoOld);
            }
            if (nodoNew != null && !nodoNew.equals(nodoOld)) {
                nodoNew.getRutasCollection().add(rutas);
                nodoNew = em.merge(nodoNew);
            }
            if (nodo1Old != null && !nodo1Old.equals(nodo1New)) {
                nodo1Old.getRutasCollection().remove(rutas);
                nodo1Old = em.merge(nodo1Old);
            }
            if (nodo1New != null && !nodo1New.equals(nodo1Old)) {
                nodo1New.getRutasCollection().add(rutas);
                nodo1New = em.merge(nodo1New);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                RutasPK id = rutas.getRutasPK();
                if (findRutas(id) == null) {
                    throw new NonexistentEntityException("The rutas with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(RutasPK id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Rutas rutas;
            try {
                rutas = em.getReference(Rutas.class, id);
                rutas.getRutasPK();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The rutas with id " + id + " no longer exists.", enfe);
            }
            Nodo nodo = rutas.getHasta();
            if (nodo != null) {
                nodo.getRutasCollection().remove(rutas);
                nodo = em.merge(nodo);
            }
            Nodo nodo1 = rutas.getDesde();
            if (nodo1 != null) {
                nodo1.getRutasCollection().remove(rutas);
                nodo1 = em.merge(nodo1);
            }
            em.remove(rutas);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Rutas> findRutasEntities() {
        return findRutasEntities(true, -1, -1);
    }

    public List<Rutas> findRutasEntities(int maxResults, int firstResult) {
        return findRutasEntities(false, maxResults, firstResult);
    }

    private List<Rutas> findRutasEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Rutas.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }
    
    public ArrayList<Rutas> findRutasEntities(Nodo nodo){
        EntityManager em = getEntityManager();
        try{
            ArrayList<Rutas> rutas = new ArrayList<Rutas>();
            EntityTransaction entr = em.getTransaction();
            entr.begin();
            Query query = em.createNamedQuery("Rutas.findByDesde");
            //query.setParameter(1, nodo.getId());
            query.setParameter("desde", nodo.getId());
            List list = query.getResultList();
            Iterator it = list.iterator();
            while(it.hasNext()){
                Rutas rt = (Rutas)it.next();
                rutas.add(rt);
            }
            return rutas;
        }
        finally {
            em.close();
        }
    }

    public Rutas findRutas(RutasPK id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Rutas.class, id);
        } finally {
            em.close();
        }
    }

    public int getRutasCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Rutas> rt = cq.from(Rutas.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
